#ifndef _SYS_BUFFER_H
#define _SYS_BUFFER_H

#include <system/syslist.h>

/* sysbuf_group_t::type */
enum
{
    SYSBUF_GROUPTYPE_SRAM=0,
    SYSBUF_GROUPTYPE_DDR,
};

typedef struct sysbuf_group
{
    uint16_t type;
    uint16_t count;
    uint32_t unitsize;
    phys_addr_t vaddr;
    phys_addr_t haddr;
} PACKED sysbuf_group_t;
typedef sysbuf_group_t *psysbuf_group_t;

typedef struct
{
    uint32_t nLowPart;
    uint32_t nHighPart;
} PACKED sysbuf_user_t;

typedef struct sysbuf
{
    struct slists list;

    uint16_t mark;
    uint16_t flags;

    phys_addr_t vaddr;
    phys_addr_t haddr;

    int32_t maxsize;
    int32_t offset;
    int32_t size;
    uint32_t buffid;

    sysbuf_user_t user;

} PACKED sysbuf_t;
typedef sysbuf_t *psysbuf_t;

#ifdef CONFIG_HIFI
# define SYS_BUF_MAX_COUNT       200
#else
# define SYS_BUF_MAX_COUNT       120
#endif

/* sys_buf_t::mark */
#define SYS_BUF_MARK            0xbead
#define SYS_BUF_ISVALID(b)      ((b)&&(b->mark==SYS_BUF_MARK))

/* sys_buf_t::flags */
#define SYS_BUF_FLAG_MARK               (0xFF00)
#define SYS_BUF_FLAG_BOT_FIRST          (0x0100)
#define SYS_BUF_FLAG_TOP_PRESENT        (0x0200)
#define SYS_BUF_FLAG_BOT_PRESENT        (0x0400)
#define SYS_BUF_FLAG_REF_FRAME          (0x0800)
#define SYS_BUF_FLAG_EOS                (0x1000)
#define SYS_BUF_FLAG_EOF                (0x8000)

/* sys_buf_t::group */
enum
{
    SYSBUF_GROUP_FREE=0,

    SYSBUF_GROUP_RAMBUFS,
    SYSBUF_GROUP_DATBUFS,

    SYSBUF_GROUP_CV_RAMBUFS,
    SYSBUF_GROUP_CV_BITBUFS,
    SYSBUF_GROUP_CV_REFBUFS,
    SYSBUF_GROUP_CV_FRMBUFS,

    SYSBUF_GROUP_NETBUFS,

    SYSBUF_GROUP_COUNT,
};

/*NOTICE, must be aligned for device dma transfer */
#define PACKET_OFFSET   0x80

#ifdef __cplusplus
extern "C" {
#endif  /* __cplusplus */

/**
 * sysbuf_init
 */
ARCHLIB_API  void sysbuf_init(void);

/**
 * sysbuf_group_set
 */
ARCHLIB_API  int sysbuf_group_reset(sysbuf_group_t *gd, int group);

/**
 *  sysbuf_free
 */
ARCHLIB_API int sysbuf_free(psysbuf_t  buf);

/**
 *  sysbuf_put
 */
ARCHLIB_API int sysbuf_put(psysbuf_t  buf);

/**
 *  sysbuf_alloc
 */
ARCHLIB_API psysbuf_t sysbuf_alloc(int group);

/**
 *  sysbuf_get
 */
ARCHLIB_API psysbuf_t sysbuf_get(int group);

/**
 *  sysbuf_from_vaddr
 */
ARCHLIB_API psysbuf_t sysbuf_from_vaddr(uint32_t vaddr);

/**
 *  sysbuf_from_haddr
 */
ARCHLIB_API  psysbuf_t sysbuf_from_haddr(uint32_t haddr);

#ifdef __cplusplus
}
#endif  /* __cplusplus */

#endif // _SYS_BUFFER_H

